package ext.tianma.workflow;


import wt.admin.AdministrativeDomainHelper;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.fc.WTObject;
import wt.inf.container.WTContained;
import wt.inf.container.WTContainerHelper;
import wt.inf.container.WTContainerRef;
import wt.org.AmbiguousPrincipalException;
import wt.org.OrganizationServicesHelper;
import wt.org.WTPrincipal;
import wt.org.WTPrincipalReference;
import wt.org.WTUser;
import wt.part.WTPart;
import wt.query.ClassAttribute;
import wt.query.OrderBy;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.session.SessionHelper;
import wt.session.SessionServerHelper;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.vc.Versioned;
import wt.workflow.definer.WfProcessTemplate;
import wt.workflow.engine.ProcessData;
import wt.workflow.engine.WfEngineHelper;
import wt.workflow.engine.WfEngineServerHelper;
import wt.workflow.engine.WfProcess;

public class SubmitBomReview {
	private static final String CLASSNAME = SubmitBomReview.class.getName() ; 
	
	public static void submitBOMReviewWorkflow(WTPart part){
		submitWorkflow( part , "天马BOM审核流程 " , false ) ;
	}
	
	/**
	 * Use Code to Start or Submit Workflow
	 * 
	 * @param pbo
	 * @param wfProcessTemplateName
	 * @param isPboCreator , use the PBO creator as workflow process creator
	 */
	public static void submitWorkflow( WTObject pbo , String wfProcessTemplateName , boolean isPboCreator ){
		System.out.println("1 : isPboCreator = " + isPboCreator ) ;
		
		if( wfProcessTemplateName == null || wfProcessTemplateName.trim().equals("")){
			System.out.println("Submit Workflow Failed." + CLASSNAME + " : method parameter wfProcessTemplateName is NULL!") ;
			return ;
		}
		
		try {
			WfProcessTemplate wfprocessTemplate = getWfProcessTemplateByName( wfProcessTemplateName ) ;
			
			System.out.println("2 : isPboCreator = " + isPboCreator ) ;
			submitWorkflow( pbo , wfprocessTemplate ,  isPboCreator ) ;
		} catch (WTException e) {
			e.printStackTrace();
		} catch (WTPropertyVetoException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Use Code to Start or Submit Workflow
	 * 
	 * @param pbo
	 * @param wfprocessTemplate
	 * @param isPboCreator , use the PBO creator as workflow process creator
	 * 
	 * @throws WTException
	 * @throws WTPropertyVetoException
	 */
	public static void submitWorkflow( WTObject pbo , WfProcessTemplate wfprocessTemplate , boolean isPboCreator ) throws WTException, WTPropertyVetoException{
		System.out.println("3 : isPboCreator = " + isPboCreator ) ;
		
		System.out.println(">>>>> Start ext.tianma.workflow.SubmitBomReview.submitWorkflow()") ;
		
		if( pbo == null ){
			System.out.println("Submit Workflow Failed." + CLASSNAME + " : PBO is NULL!") ;
			return ;
		}
		
		if( wfprocessTemplate == null ){
			System.out.println("Submit Workflow Failed." + CLASSNAME + " : method parameter wfprocessTemplate is NULL!") ;
			return ;
		}
		
		boolean flag = SessionServerHelper.manager.setAccessEnforced(false);
		
		try{
			WTContainerRef wtcontainerref = getWTContainerRef( pbo ) ;
			
			//Create Workflow Process
			WfProcess wfprocess = WfEngineHelper.service.createProcess( wfprocessTemplate , pbo , wtcontainerref );
			
			System.out.println(">>>>> Create Workflow Process End ......") ;
			
			// Set Workflow PBO
			WfEngineServerHelper.service.setPrimaryBusinessObject(wfprocess,pbo);
			
			System.out.println(">>>>> Set Workflow Process PBO object End ......") ;
			
			//Set Workflow Name
			String processName = getProcessName( pbo , wfprocessTemplate ) ;
			
			System.out.println(">>>>> Workflow Process Name = " + processName ) ;
			
			wfprocess.setName( processName );
			
			System.out.println(">>>>> Set Workflow Process Name End ......") ;
			
			// Set Workflow Creator
			System.out.println("4 : isPboCreator = " + isPboCreator ) ;
			
			WTPrincipalReference wtprincipalreference = getProcessCreator( pbo , wfprocessTemplate , isPboCreator ) ;
			System.out.println("wtprincipalreference===>>"+wtprincipalreference.getFullName());
			WTPrincipal prin = SessionHelper.manager.getPrincipal();
			wfprocess.setCreator(WTPrincipalReference.newWTPrincipalReference(prin));
			System.out.println(WTPrincipalReference.newWTPrincipalReference(prin).getFullName());
			System.out.println("creator=====getFullName======="+wtprincipalreference.getFullName());
			System.out.println("creator=====getName======="+wtprincipalreference.getName());
			wfprocess.setCreator(wtprincipalreference);
			
			System.out.println("====creator===getCreator=="+wfprocess.CREATOR);
			
			
			System.out.println(">>>>> Save Workflow Process Start ......") ;
			
			wfprocess = (WfProcess)PersistenceHelper.manager.save(wfprocess);
			
			System.out.println(">>>>> Save Workflow Process End ......") ;
			
			//Start Workflow
			ProcessData processdata = wfprocess.getContext();
			
			System.out.println(">>>>> Warning : Workflow Process Start by Code ......") ;
			
			wfprocess.start(processdata, true, wtcontainerref );
			
			System.out.println(">>>>> Warning : Workflow Process Start by Code Successfully ......") ;
		}finally{
			SessionServerHelper.manager.setAccessEnforced(flag);
		}
		
		System.out.println(">>>>> End ext.tianma.workflow.SubmitBomReview.submitWorkflow()") ;
	}

	/**
	 * Get WfProcessTemplate by it's Name
	 * 
	 * @param wfProcessTemplateName
	 * 
	 * @return WfProcessTemplate
	 * 
	 * @throws WTException
	 */
	public static WfProcessTemplate getWfProcessTemplateByName( String wfProcessTemplateName ) throws WTException{
		QueryResult queryResult = queryWfProcessTemplateByName( wfProcessTemplateName ) ;
		
		WfProcessTemplate wfprocessTemplate = null ;
		
		if( queryResult != null && queryResult.hasMoreElements() ){
			Object obj = queryResult.nextElement() ;
			
			if( obj != null && obj instanceof WfProcessTemplate ){
				wfprocessTemplate = ( WfProcessTemplate ) obj ;
			}
		}
		
		return wfprocessTemplate ;
	}
	
	/**
	 * Query WfProcessTemplate by it's Name
	 * 
	 * @param wfProcessTemplateName
	 * 
	 * @return QueryResult
	 * 
	 * @throws WTException
	 */
	public static QueryResult queryWfProcessTemplateByName( String wfProcessTemplateName ) throws WTException{
		QuerySpec querysearch = new QuerySpec(WfProcessTemplate.class);

		SearchCondition sc = new SearchCondition(WfProcessTemplate.class, "name", SearchCondition.EQUAL, wfProcessTemplateName );
		
		querysearch.appendWhere(sc);
		
		// true为降序，false为升序
		OrderBy orderby = new OrderBy(new ClassAttribute(WfProcessTemplate.class, "thePersistInfo.createStamp"), true);
		
		querysearch.appendOrderBy(orderby, 0);

		QueryResult queryresult = PersistenceHelper.manager.find(querysearch);
		
		return queryresult ;
	}
	
	private static String getProcessName( WTObject pbo , WfProcessTemplate wfprocessTemplate ){
		StringBuffer processName = new StringBuffer("") ;
		
		if( wfprocessTemplate != null ){
			processName.append( wfprocessTemplate.getName() ) ;
		}
		
		if( processName.length() > 0 ){
			processName.append(" - ") ;
		}
		
		processName.append( pbo.getDisplayIdentifier() ) ;

		return processName.toString() ;
	}
	
	private static WTPrincipalReference getProcessCreator( WTObject pbo , WfProcessTemplate wfprocessTemplate , boolean isPboCreator ) throws WTException{
		System.out.println("5 : isPboCreator = " + isPboCreator ) ;
		
		WTPrincipalReference wtprincipalreference = null ;

		if( isPboCreator ){
			System.out.println(">>>>> Use PBO Creator!") ;
			
			wtprincipalreference = getCreator( pbo );
		}else{
			System.out.println(">>>>> Use Session User!") ;
			
			WTPrincipal principal = SessionHelper.getPrincipal() ;
			
			if( principal != null ){
				wtprincipalreference = WTPrincipalReference.newWTPrincipalReference( principal );
			}
			
			if( principal == null ){
				wtprincipalreference = getCreator( pbo );
			}
		}
		
		if( wtprincipalreference == null ){
			WTUser wtuser = getAdministrator() ;
			
			if( wtuser != null ){
				wtprincipalreference = WTPrincipalReference.newWTPrincipalReference(wtuser);
			}
		}
		
		if( wtprincipalreference != null ){
			System.out.println(">>>>> Get Workflow Process Process Creator: ProcessCreator = " + wtprincipalreference.getFullName() ) ;
		}else{
			System.out.println(">>>>> wtprincipalreference == null") ;
		}

		return wtprincipalreference ;
	}

	private static WTPrincipalReference getCreator( WTObject pbo ) throws WTException {
		WTPrincipalReference wtprincipalreference = null ;
		
		if( pbo != null && pbo instanceof Versioned ){
			Versioned versioned = ( Versioned ) pbo ;
			wtprincipalreference = versioned.getCreator();
		}
		
		return wtprincipalreference;
	}
	
	public static WTUser getAdministrator() throws WTException {
		WTUser wtuser = null;
	    
		boolean bool = SessionServerHelper.manager.setAccessEnforced(false);
	    
		try{
			wtuser = OrganizationServicesHelper.manager.getUser(AdministrativeDomainHelper.ADMINISTRATOR_NAME, OrganizationServicesHelper.ldapManager.getDirectoryContextProvider(null));
		}catch (AmbiguousPrincipalException e){
			e.printStackTrace() ;
		}finally{
			SessionServerHelper.manager.setAccessEnforced(bool);
		}

	    return wtuser;
	  }

	private static WTContainerRef getWTContainerRef(WTObject pbo) throws WTException {
		WTContainerRef wtcontainerref = null ;
		
		if( pbo != null && pbo instanceof WTContained){
			WTContained wtcontained = ( WTContained ) pbo ;
			
			wtcontainerref = wtcontained.getContainerReference() ;
		}
		
		if( wtcontainerref == null ){
			//获取默认的上下文
			wtcontainerref = WTContainerHelper.service.getExchangeRef();
		}
		
		if( wtcontainerref != null ){
			System.out.println(">>>>> wtcontainerref = " + wtcontainerref.getName() ) ;
		}else{
			System.out.println(">>>>> wtcontainerref != null") ;
		}
		
		return wtcontainerref ;
	}
}
